
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import javax.swing.JPanel;

public class DrawingPanel extends JPanel  implements MouseListener, MouseMotionListener{
    
    private boolean dragging, right_click;
    private ArrayList<Point> intersections;
    private ArrayList<Line> segments;
    private int x1, x2, y1, y2, x_offset, y_offset, xmpos, ympos, xgap, ygap;
    private double zoom;
    private MainFrame mainFrame;
    
    public DrawingPanel(MainFrame frame){
        super();
        mainFrame = frame;
        zoom = 1;
        dragging = false;
        right_click = false;
        segments = new ArrayList<Line>();
        intersections = new ArrayList<Point>();
        setBackground(Color.white);
        addMouseListener(this);
        addMouseMotionListener(this);
    }

        public void setZoom(double zoom_value){
        double old_zoom_level = zoom;
        zoom = zoom_value;
        double factor = zoom / old_zoom_level;
        double width = factor * getWidth();
        double height = factor * getHeight();
        setPreferredSize(new Dimension((int) width, (int) height));
        repaint();
        revalidate();
    }
        
    public void setLines(ArrayList<Line> new_lines){
        segments = new_lines;
        mainFrame.setNumberOfSegments(segments.size());
        repaint();
    }
    
    public ArrayList<Line> getLines(){
        return segments;
    }
    
    public void setIntersections(ArrayList<Point> points){
        intersections = points;
        repaint();
    }
    
    public ArrayList<Point> getIntersections(){
        return intersections;
    }
    
    public void undo(){
        if(segments.size() != 0){
            segments.remove(segments.size() -1);
            repaint();
            mainFrame.setNumberOfSegments(segments.size());
        }
    }
    
    public void clear(){
        segments = new ArrayList<Line>();
        intersections = new ArrayList<Point>();
        repaint();
    }
        
    public void mousePressed(MouseEvent me) {
        x1 =  me.getX();
        y1 =  me.getY();
        dragging = true;
        if(me.getButton() == me.BUTTON3) right_click = true;
    }

    public void mouseReleased(MouseEvent me) {
        if(me.getButton() == me.BUTTON1){
            x2 = me.getX();
            y2 = me.getY();
            if(x1 != x2 || y1 != y2){
                Point p1 = new Point(x1 / zoom, (getHeight() - y1) / zoom);
                Point p2 = new Point(x2 / zoom, (getHeight() - y2) / zoom);
                Line l = new Line(p1, p2);
                l.setOffset(x_offset, y_offset);
                segments.add(l);
                mainFrame.setNumberOfSegments(segments.size());
            repaint();
            }
        }
        else if(me.getButton() == me.BUTTON3){
            //TODO mettre à jour l'offest lors des déplacement en considérant le gap par rapport à l'offset précédent.
            //x_offset = x_offset + xgap;
            //y_offset = y_offset + ygap;
            repaint();
            right_click = false;
        }
        dragging = false;
    }

    public void mouseDragged(MouseEvent me) {
        xmpos = me.getX();
        ympos = me.getY();
        if(dragging){
            x2 = me.getX();
            y2 = me.getY();
            if(right_click){
                System.out.println("gapx: " + xgap + "  gapy: " + ygap);
                x_offset = x_offset - xgap;
                y_offset = y_offset - ygap;
                xgap = x2 - x1;
                ygap = y2 - y1;
                x_offset = x_offset + xgap;
                y_offset = y_offset + ygap;
            }
            repaint();
        }
    }
    
    public void paintComponent(Graphics g){
        Graphics2D g2 = (Graphics2D) g;
        g2.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ));
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
        g2.scale(zoom, zoom);
        super.paintComponent(g2);
        for(Line line: segments){
            int x1 = (int) (line.getX1() + line.getXOffset()) + x_offset;
            int x2 = (int) (line.getX2() + line.getXOffset()) + x_offset;
            int y1 = (int) (getHeight()/zoom - line.getY1() + line.getYOffset()) + y_offset;
            int y2 = (int) (getHeight()/zoom - line.getY2() + line.getYOffset()) + y_offset;
            System.out.println(x1 + "," + y1 + "      " + x2 + "," + y2);
            g2.drawLine(x1, y1, x2, y2);
        }
        g2.setColor(Color.red);
        for(Point point: intersections){
            int x = (int) point.getX() + x_offset -1;
            int y = (int) (getHeight()/zoom - point.getY() + y_offset) -1;
            g2.drawOval(x, y, 1, 1);
        }
        g2.setColor(Color.blue);
        if(!right_click && dragging){
            int xp1 = (int) (x1 / zoom);
            int yp1 = (int) (y1 / zoom);
            int xp2 = (int) (x2 / zoom);
            int yp2 = (int) (y2 / zoom);
            g2.drawLine(xp1, yp1, xp2, yp2);
        }
        int a = (int) (xmpos / zoom) + x_offset;
        int b = (int) (ympos / zoom) + y_offset;
        g2.drawString("(" + a + "," + (getHeight() - b) + ")",(int) (xmpos / zoom), (int) (ympos / zoom));
    }

    public void mouseClicked(MouseEvent me) {
       //Do nothing
    }
    
    public void mouseEntered(MouseEvent me) {
        //Do nothing
    }
    
    public void mouseExited(MouseEvent me) {
        //Do nothing
    }
    
    public void mouseMoved(MouseEvent me) {
        xmpos = me.getX();
        ympos = me.getY();
        repaint();
    }
}
